package micotime.com.amap_plugin.map;

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.view.View;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.route.RouteSearch;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.flutter.Log;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.JSONUtil;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
import micotime.com.amap_plugin.map.channel.AMapViewMethodChannel;
import micotime.com.amap_plugin.map.channel.CameraUpdateMethodChannel;
import micotime.com.amap_plugin.map.channel.IMethodChannel;
import micotime.com.amap_plugin.map.channel.MarkerMethodChannel;
import micotime.com.amap_plugin.map.common.LocationUtils;
import micotime.com.amap_plugin.map.model.UnifiedAMapOptions;


public class AMapView implements PlatformView,
        MethodChannel.MethodCallHandler,
        LocationSource, AMapLocationListener,
        AMap.OnMapClickListener,
        AMap.OnMyLocationChangeListener,
        AMap.OnMarkerClickListener,
        AMap.OnCameraChangeListener {

    String TAG = "AMapView";


    public static final String METHOD_CHANNEL_NAME_MAP_VIEW = "plugins.yanwc/amap_view_";

    /**
     * 位置变更事件
     */
    private final static String METHOD_CHANNEL_ON_LOCATION_CHANGED = "onLocationChanged";

    /**
     * 地图点击
     */
    private final static String METHOD_CHANNEL_ON_MAP_CHANGED = "onMapClick";

    private final static String METHOD_CHANEL_ON_LOCATION_CHANGED="onLocationChanged";

    //调用flutter方法通道
    private MethodChannel flutterMethodChannel;

    private TextureMapView aMapView; //地图视图
    private AMap aMap; //地图配置
    private AMapLocationClient mLocationClient;
    private AMapLocationClientOption mLocationOption;
    private LocationSource.OnLocationChangedListener mListener;
    private RouteSearch routeSearch;//路线规划

    private Context context;

    private List<IMethodChannel> methodChannels = new ArrayList<>();

    public AMapView(Context context, BinaryMessenger messenger,
                    int id, UnifiedAMapOptions unifiedAMapOptions) {
        this.context = context;
        aMapView = new TextureMapView(context, unifiedAMapOptions.getOptions());
        aMapView.onCreate(new Bundle());
        aMap = aMapView.getMap();
        // 设置定位监听
        aMap.setLocationSource(this);
        // 设置默认定位按钮是否显示
        aMap.getUiSettings().setMyLocationButtonEnabled(unifiedAMapOptions.isMyLocationButtonEnabled());
        MyLocationStyle myLocationStyle = unifiedAMapOptions.getMyLocationStyle();
        myLocationStyle.showMyLocation(unifiedAMapOptions.isShowMyLocation());
        myLocationStyle.myLocationType(unifiedAMapOptions.getLocationType());
        aMap.setMyLocationStyle(myLocationStyle);
        // 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        aMap.setMyLocationEnabled(unifiedAMapOptions.isMyLocationEnabled());

        //添加地图事件
        aMap.setOnMapClickListener(this);
        aMap.setOnMyLocationChangeListener(this);
        aMap.setOnMarkerClickListener(this);

        //被调用方法通道
        methodChannels.add(new CameraUpdateMethodChannel(context, aMapView));
        methodChannels.add(new MarkerMethodChannel(context,aMapView));
        methodChannels.add(new AMapViewMethodChannel(context,aMapView));

        //调用Flutter方法的通道
        flutterMethodChannel = new MethodChannel(messenger, METHOD_CHANNEL_NAME_MAP_VIEW + String.valueOf(id));
        flutterMethodChannel.setMethodCallHandler(this);
    }

    @Override
    public View getView() {
        return aMapView;
    }

    @Override
    public void dispose() {
        aMapView.onDestroy();
        flutterMethodChannel.setMethodCallHandler(null);
        aMapView = null;
        aMap = null;
        routeSearch = null;
    }

    @Override
    public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
        for (IMethodChannel methodChannel : methodChannels) {
            methodChannel.process(methodCall, result);
        }
    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if(mLocationClient == null){
            //初始化定位
            mLocationClient = new AMapLocationClient(this.context);
            //初始化定位参数
            mLocationOption = new AMapLocationClientOption();
            //设置定位回调监听
            mLocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mLocationClient.setLocationOption(mLocationOption);

            for (IMethodChannel methodChannel : methodChannels) {
                methodChannel.setaMapLocationClient(mLocationClient);
            }
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mLocationClient.startLocation();//启动定位
        }
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }

    @Override
    public void onMapClick(LatLng latLng) {
        Log.d(TAG, "lat:" + String.valueOf(latLng.latitude) + "   lng:" + String.valueOf(latLng.longitude));
        Map<String, Object> map = new HashMap<>();
        map.put("lat", latLng.latitude);
        map.put("lng", latLng.longitude);
        flutterMethodChannel.invokeMethod(METHOD_CHANNEL_ON_MAP_CHANGED, new JSONObject(map).toString());
    }

    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点

            } else {
                String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
            this.flutterMethodChannel.invokeMethod(METHOD_CHANEL_ON_LOCATION_CHANGED,aMapLocation);
        }
    }

    @Override
    public void onMyLocationChange(Location location) {
        flutterMethodChannel.invokeMethod(METHOD_CHANNEL_ON_LOCATION_CHANGED, LocationUtils.getLocationInfoMap(location));
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        return false;
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {

    }

    /*
    @Override
    public void onPoiSearched(PoiResult poiResult, int i) {

    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

     */
}
